/*
 * @Author: Wangjun
 * @Date: 2021-05-15 22:43:19
 * @LastEditTime: 2021-08-09 17:13:43
 * @LastEditors: Wangjun
 * @Description:
 * @FilePath: \golib\iotools\iotools.go
 * hnxr
 */
package iotools

import (
	"encoding/binary"
	"errors"
	"io"

	"gitee.com/haodreams/golib/lz4file"
	"gitee.com/haodreams/libs/sock"
)

// PacketHeadLength 包头的长度
const PacketHeadLength = 2

// Send 发送
func Send(w io.Writer, data []byte) (n int, err error) {
	isCompressed := false
	//如果压缩后的数据小于没压缩的数据,不添加标志位

	buf, err := lz4file.Encode(data)
	if err == nil {
		if len(buf) < len(data) {
			isCompressed = true
			//logs.Debug("压缩掉字节数", len(data), len(buf), len(data)-len(buf))
			//logs.Debug("压缩后大小:", len(buf), "源数据包大小:", len(data), "压缩掉的字节:", len(data)-len(buf))
			data = buf
		}
	}

	l := len(data)
	if isCompressed {
		l |= 0x8000
	}
	buf = make([]byte, PacketHeadLength)
	binary.BigEndian.PutUint16(buf, uint16(l))
	buf = append(buf, data...)
	n, err = w.Write(buf)
	n -= 2
	return
}

// Recv 接收
// 在原始的tcp数据留上加上2字节报文头
// 最高位为1表示要解压缩
func Recv(r io.Reader) (data []byte, err error) {
	buf := make([]byte, PacketHeadLength)
	n, err := sock.Read(r, buf)
	if err != nil {
		return
	}
	if n != PacketHeadLength {
		err = errors.New("receive head error")
		return
	}
	l := binary.BigEndian.Uint16(buf)
	isCompressed := true
	if l&0x8000 == 0 {
		isCompressed = false
	}
	l &= 0x7fff
	data = make([]byte, l)
	_, err = sock.Read(r, data)
	if err != nil {
		return
	}
	if isCompressed { //解压缩
		data, err = lz4file.Decode(data)
		//logs.Debug("解压后大小:", len(data), "源数据包大小:", l, "压缩掉的字节:", len(data)-int(l))
		//logs.Debug("计算压缩处理字节", l, len(data), len(data)-int(l))
	}
	return
}
